home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
uae-0.000
/
uae-0
/
uae-0.6.0
/
bebox.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-12
|
14KB
|
636 lines
/*
* UAE - The Un*x Amiga Emulator
*
* BeBox port specific stuff
*
* (c) 1996 Christian Bauer
*/
#include <AppKit.h>
#include <InterfaceKit.h>
#include <KernelKit.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define __STDC__ 1
#define __GNU_LIBRARY__
#include <getopt.h>
#undef __GNU_LIBRARY__
#undef __STDC__
#ifndef __bebox__
#error Compiling bebox.cpp, but __bebox__ unset.
#endif
extern "C" {
#include "sysconfig.h"
#include "sysdeps.h"
#include "config.h"
#include "options.h"
#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "disk.h"
#include "debug.h"
#include "xwin.h"
#include "os.h"
#include "filesys.h"
#include "keybuf.h"
#include "keyboard.h"
}
class UAEWindow;
class BitmapView;
class Emulator;
/*
* The BeOS application object
*/
class UAE : public BApplication {
public:
UAE();
virtual void ArgvReceived(int argc, char **argv);
virtual void ReadyToRun(void);
virtual bool QuitRequested(void);
virtual void AboutRequested(void);
private:
BBitmap *the_bitmap;
UAEWindow *main_window;
Emulator *the_emulator;
};
/*
* The window in which the Amiga graphics are displayed, handles I/O
*/
class UAEWindow : public BWindow {
public:
UAEWindow(BRect frame, BBitmap *bitmap);
virtual bool QuitRequested(void);
virtual void WindowActivated(bool active);
private:
BitmapView *main_view;
};
/*
* A simple view class for blitting a bitmap on the screen
*/
class BitmapView : public BView {
public:
BitmapView(BRect frame, BBitmap *bitmap);
virtual void Draw(BRect update);
void Draw(BRect from, BRect to);
private:
BBitmap *the_bitmap;
};
/*
* For running the emulation in its own thread
*/
class Emulator {
public:
Emulator() {thread_running = FALSE;}
void Run(void);
void Quit(void);
private:
static long thread_invoc(Emulator *obj);
void thread_func(void);
thread_id the_thread;
bool thread_running;
};
// Keyboard and mouse
int buttonstate[3];
int newmousecounters;
int lastmx, lastmy;
key_info old_key_info;
bool inwindow;
bool window_open;
// Color map and bitmap
xcolnr xcolors[4096];
struct vidbuf_description gfxvidinfo;
int vsize, hsize, hpixels;
BitmapView *bitmap_view;
UAEWindow *bitmap_window;
// Array for converting Be keycodes to Amiga keycodes
int keycode2amiga[128] = {
-1, AK_ESC, AK_F1, AK_F2, AK_F3, AK_F4, AK_F5, AK_F6,
AK_F7, AK_F8, AK_F9, AK_F10, AK_LALT, AK_mousestuff, AK_RALT, -1,
-1, AK_BACKQUOTE, AK_1, AK_2, AK_3, AK_4, AK_5, AK_6,
AK_7, AK_8, AK_9, AK_0, AK_MINUS, AK_EQUAL, AK_BS, AK_HELP,
AK_NPLPAREN, AK_RAMI, AK_NPLPAREN, AK_NPDIV, AK_NPMUL, AK_NPSUB, AK_TAB, AK_Q,
AK_W, AK_E, AK_R, AK_T, AK_Y, AK_U, AK_I, AK_O,
AK_P, AK_LBRACKET, AK_RBRACKET, AK_BACKSLASH, AK_DEL, AK_NPRPAREN, AK_LAMI, AK_NP7,
AK_NP8, AK_NP9, AK_NPADD, AK_CAPSLOCK, AK_A, AK_S, AK_D, AK_F,
AK_G, AK_H, AK_J, AK_K, AK_L, AK_SEMICOLON, AK_QUOTE, AK_RET,
AK_NP4, AK_NP5, AK_NP6, AK_LSH, AK_Z, AK_X, AK_C, AK_V,
AK_B, AK_N, AK_M, AK_COMMA, AK_PERIOD, AK_SLASH, AK_RSH, AK_UP,
AK_NP1, AK_NP2, AK_NP3, AK_ENT, AK_CTRL, AK_LAMI, AK_SPC, AK_RAMI,
AK_RALT, AK_LF, AK_DN, AK_RT, AK_NP0, AK_NPDEL, AK_LALT, AK_RALT,
AK_LTGT, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1
};
/*
* Create application object and start it
*/
main()
{
UAE *the_app;
the_app = new UAE();
the_app->Run();
delete the_app;
return 0;
}
/*
* UAE Constructor: Initialize member variables
*/
UAE::UAE() : BApplication('UAEm')
{
the_bitmap = NULL;
the_emulator = NULL;
main_window = NULL;
window_open = FALSE;
}
/*
* Parse command line options
*/
void usage(void)
{
printf("UAE - The Un*x Amiga emulator\n");
printf("Summary of command-line options:\n");
printf(" -h : Print help\n");
printf(" -m VOLNAME:mount_point : mount file system at <mount point> as AmigaDOS\n"
" volume VOLNAME:\n");
printf(" -M VOLNAME:mount_point : like -m, but mount read-only\n");
printf(" -a : Don't mount the harddisk file automatically.\n"
" Useful only for testing.\n");
printf(" -s : Emulate 1MB slow memory at 0xC00000\n");
printf(" -F n : Emulate n MB fast memory at 0x200000\n");
printf(" -f n : Set the frame rate to 1/n\n");
printf(" -d : Draw the screen with the right aspect\n");
printf(" -D : Start up the built-in debugger\n");
printf(" -[0123] file : Use file instead of df[0123].adf as disk image file\n");
printf(" -r file : Use file as ROM image instead of kick.rom\n");
printf(" -p filename : Use filename to save printer output (may be LPT1: ?)\n");
printf(" -J : Fake joystick emulation with the numeric pad.\n");
printf(" -g : Turn on gfx-lib replacement.\n");
printf(" -d mode : Select resolution with the mode parameter.\n");
printf(" -H mode : Set the number of colors with the mode parameter.\n");
printf("\n");
printf("Valid resolutions: 0 (320x200); 1 (320x240); 2 (320x400); 3 (800x600);\n"
" 4 (800x600, correct aspect)\n"
"Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n"
"UAE may choose to ignore the color mode/resolution setting.\n");
}
void UAE::ArgvReceived(int argc, char **argv)
{
int c;
while(((c = getopt(argc, argv, "Df:gd:hF:asJm:M:0:1:2:3:r:H:p:")) != EOF)) switch(c) {
case 'h': usage(); exit(0);
case '0': strncpy(df0, optarg, 255); df0[255] = 0; break;
case '1': strncpy(df1, optarg, 255); df1[255] = 0; break;
case '2': strncpy(df2, optarg, 255); df2[255] = 0; break;
case '3': strncpy(df3, optarg, 255); df3[255] = 0; break;
case 'r': strncpy(romfile, optarg, 255); romfile[255] = 0; break;
case 'p': strncpy(prtname, optarg, 255); prtname[255] = 0; break;
case 'm':
case 'M':
{
/* mount file system (repeatable)
* syntax: [-m | -M] VOLNAME:/mount_point
* example: -M CDROM:/cdrom -m UNIXFS:./disk
*/
static int mount_seen = 0;
char buf[256];
char *s2;
int readonly = (c == 'M');
if (mount_seen)
fprintf(stderr, "warning: multiple mounts confuse Kickstart 1.3\n");
mount_seen = 1;
strncpy(buf, optarg, 255); buf[255] = 0;
s2 = strchr(buf, ':');
if(s2) {
*s2++ = '\0';
add_filesys_unit(buf, s2, readonly);
} else {
fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n");
}
}
break;
case 'f': framerate = atoi(optarg); break;
case 'D': use_debugger = 1; break;
case 'J': fake_joystick = 1; break;
case 'a': automount_uaedev = 0; break;
case 's': use_slow_mem = 1; break;
case 'g': use_gfxlib = 1; break;
case 'F':
fastmem_size = atoi(optarg) * 0x100000;
if (fastmem_size != 0x100000 && fastmem_size != 0x200000
&& fastmem_size != 0x400000 && fastmem_size != 0x800000)
{
fastmem_size = 0;
fprintf(stderr, "Unsupported fastmem size!\n");
}
break;
case 'd':
screen_res = atoi(optarg);
if (screen_res >= 0 && screen_res <= 4) {
} else {
fprintf(stderr, "Bad video mode selected. Using default.\n");
screen_res = 3;
}
dont_want_aspect = screen_res != 4;
use_lores = screen_res < 3;
break;
case 'H':
color_mode = atoi(optarg);
if (color_mode < 0 || color_mode > 2) {
fprintf(stderr, "Bad color mode selected. Using default.\n");
color_mode = 0;
}
break;
}
}
/*
* Arguments processed, create and start emulation
*/
void UAE::ReadyToRun(void)
{
vsize = dont_want_aspect ? numscrlines : numscrlines*2;
hsize = use_lores ? 400 : 800;
hpixels = use_lores ? 320 : 796;
// Allocate bitmap
the_bitmap = new BBitmap(BRect(0, 0, hsize-1, vsize-1), B_COLOR_8_BIT);
// Set up vidinfo
gfxvidinfo.bufmem = (char *)the_bitmap->Bits();
gfxvidinfo.rowbytes = the_bitmap->BytesPerRow();
gfxvidinfo.pixbytes = 1;
gfxvidinfo.maxblocklines = 100;
// Open window
main_window = new UAEWindow(BRect(0, 0, hpixels-1, vsize-1), the_bitmap);
// Initialize mouse and keyboard variables
buttonstate[0] = buttonstate[1] = buttonstate[2] = FALSE;
lastmx = lastmy = 0;
newmousecounters = FALSE;
inwindow = TRUE;
// Start emulation
the_emulator = new Emulator;
the_emulator->Run();
}
/*
* Quit requested (either by menu or by closing the window)
*/
bool UAE::QuitRequested(void)
{
if (BApplication::QuitRequested()) {
// Stop emulation
if (the_emulator) {
the_emulator->Quit();
delete the_emulator;
}
// Deallocate bitmap
if (the_bitmap)
delete the_bitmap;
return TRUE;
}
return FALSE;
}
/*
* Display "about" window
*/
void UAE::AboutRequested(void)
{
char str[256];
sprintf(str, "UAE V0.5.3 by Bernd Schmidt\nBeBox port by Christian Bauer");
BAlert *the_alert = new BAlert("", str, "OK");
the_alert->Go();
}
/*
* UAE Window constructor
*/
UAEWindow::UAEWindow(BRect frame, BBitmap *bitmap) : BWindow(frame, "UAE", B_TITLED_WINDOW, B_NOT_RESIZABLE)
{
int r, g, b, i;
// Move window to right position
MoveTo(80, 60);
// Create bitmap view
Lock();
main_view = new BitmapView(frame, bitmap);
AddChild(main_view);
main_view->GetKeys(&old_key_info, FALSE);
Unlock();
bitmap_view = main_view;
bitmap_window = this;
// Initialize xcolors
i = 0;
for (r=0; r<16; r++) {
for (g=0; g<16; g++) {
for (b=0; b<16; b++)
xcolors[i++] = index_for_color(r<<4 | r, g<<4 | g, b<<4 | b);
}
}
// Show window
Show();
window_open = TRUE;
}
/*
* Closing the window quits UAE
*/
bool UAEWindow::QuitRequested(void)
{
window_open = FALSE;
be_app->PostMessage(B_QUIT_REQUESTED);
return TRUE;
}
/*
* Window was (de)activated
*/
void UAEWindow::WindowActivated(bool active)
{
inwindow = active;
}
/*
* Bitmap view constructor
*/
BitmapView::BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "", B_FOLLOW_NONE, B_WILL_DRAW)
{
the_bitmap = bitmap;
}
/*
* Blit the bitmap
*/
void BitmapView::Draw(BRect update)
{
DrawBitmap(the_bitmap, update, update);
}
void BitmapView::Draw(BRect from, BRect to)
{
DrawBitmap(the_bitmap, from, to);
}
/*
* Start main emulation thread
*/
void Emulator::Run(void)
{
// Initialize everything
produce_sound = FALSE;
init_joystick();
keybuf_init ();
memory_init();
custom_init();
DISK_init();
init_m68k();
MC68000_reset();
// Start the emulation thread
the_thread = spawn_thread(thread_invoc, "UAE 68000", B_NORMAL_PRIORITY, this);
resume_thread(the_thread);
thread_running = TRUE;
}
/*
* Stop main emulation thread
*/
void Emulator::Quit(void)
{
// Kill the thread if it is running
if (thread_running) {
kill_thread(the_thread);
thread_running = FALSE;
}
close_joystick();
}
/*
* The thread's main function
*/
long Emulator::thread_invoc(Emulator *obj)
{
obj->thread_func();
return 0;
}
void Emulator::thread_func(void)
{
// This jumps to MC68000_run() and executes the main loop
debug();
thread_running = FALSE;
}
/*
* Redraw a line
*/
void flush_line(int y)
{
if (window_open) {
bitmap_window->Lock();
bitmap_view->Draw(BRect(0, y, hpixels-1, y));
bitmap_window->Unlock();
}
}
/*
* Redraw a block
*/
void flush_block(int ystart, int ystop)
{
int xs = use_lores ? prev_max_diwstop - 328 : 0;
if (window_open) {
bitmap_window->Lock();
bitmap_view->Draw(BRect(xs, ystart, hpixels+xs-1, ystop), BRect(0, ystart, hpixels-1, ystop));
bitmap_window->Unlock();
}
}
/*
* Redraw the screen
*/
void flush_screen(int ystart, int ystop)
{
}
/*
* Poll mouse and keyboard
*/
void handle_events(void)
{
key_info the_key_info;
int be_code, be_byte, be_bit, amiga_code;
BPoint mouse_point;
ulong mouse_buttons;
// Keyboard
if (window_open && inwindow) {
bitmap_window->Lock();
bitmap_view->GetKeys(&the_key_info, FALSE);
bitmap_window->Unlock();
for (be_code=0; be_code<0x80; be_code++) {
be_byte = be_code >> 3;
be_bit = 1 << (~be_code & 7);
// Key state changed?
if ((the_key_info.key_states[be_byte] & be_bit)
!= (old_key_info.key_states[be_byte] & be_bit)) {
amiga_code = keycode2amiga[be_code];
if (the_key_info.key_states[be_byte] & be_bit) {
// Key pressed
if (amiga_code == AK_mousestuff)
togglemouse();
else
record_key(amiga_code << 1);
} else {
// Key released
record_key((amiga_code << 1) | 1);
}
}
}
old_key_info = the_key_info;
// "Affengriff"
if ((the_key_info.key_states[0x5c >> 3] & (1 << (~0x5c & 7)))
&& (the_key_info.key_states[0x5d >> 3] & (1 << (~0x5d & 7)))
&& (the_key_info.key_states[0x5f >> 3] & (1 << (~0x5f & 7))))
MC68000_reset();
// Scroll lock toggles inhibit_frame
inhibit_frame = the_key_info.key_states[0x0f >> 3] & (1 << (~0x0f & 7));
}
// Mouse
if (window_open && inwindow) {
bitmap_window->Lock();
bitmap_view->GetMouse(&mouse_point, &mouse_buttons, FALSE);
bitmap_window->Unlock();
lastmx = mouse_point.x;
lastmy = mouse_point.y;
buttonstate[0] = mouse_buttons & B_PRIMARY_MOUSE_BUTTON;
buttonstate[1] = mouse_buttons & B_TERTIARY_MOUSE_BUTTON;
buttonstate[2] = mouse_buttons & B_SECONDARY_MOUSE_BUTTON;
}
}
int debuggable(void)
{
return TRUE;
}
int needmousehack(void)
{
return TRUE;
}
void LED(int on)
{
}